package backend.Algoritmos;
import java.util.*;

import com.dp.client.dto.Fecha;

import backend.estructuras.common.*;


public class GeneradorDeRutas {
	private static List<LinkedList<Vuelo>> generaRutasDirectas(Almacen origen, Almacen destino, Fecha fechaInicio, Fecha tiempoVacio){
		Vector<Vuelo> vuelos = origen.getVuelosEnIntervaloDeTiempo(destino, fechaInicio, Fecha.suma(fechaInicio, (tiempoVacio)));
		LinkedList<LinkedList<Vuelo>> rutas = new LinkedList<>();
		for(Vuelo vuelo : vuelos){
			LinkedList<Vuelo> listaVuelo = new LinkedList<>();
			listaVuelo.add(vuelo);
			rutas.add(listaVuelo);
		}
		return rutas;
	}
	
	private static List<LinkedList<Vuelo>> generaRutasConUnaEscala(Almacen origen, Almacen destino, Fecha fechaInicio, Fecha tiempoVacio, 
			List<Almacen> escalas){
		LinkedList<LinkedList<Vuelo> > rutas = new LinkedList<>();
		for(Almacen otro : escalas){
			Vector<Vuelo> intermedios1 = 
					origen.getVuelosEnIntervaloDeTiempo(otro, fechaInicio, Fecha.suma(fechaInicio, Fecha.nextHora(tiempoVacio)));
				
			for(Vuelo intermedio1 : intermedios1){
				List<LinkedList<Vuelo>> intermedios2 = generaRutasDirectas(otro, destino, intermedio1.getFechaLlegada(),
						Fecha.resta(tiempoVacio, Fecha.resta(intermedio1.getFechaSalida(), fechaInicio)));
				for(LinkedList<Vuelo> lista : intermedios2){
					LinkedList<Vuelo> ruta = new LinkedList<>();
					ruta.add(intermedio1);
					ruta.addAll(lista);
					rutas.add(ruta);
				}
			}
		}
		return rutas;
	}
	private static List<LinkedList<Vuelo>> generaRutasConDosEscalas(Almacen origen, Almacen destino, Fecha fechaInicio, Fecha tiempoVacio, 
			List<Almacen> escalas1, List<Almacen> escalas2){
		LinkedList<LinkedList<Vuelo> > rutas = new LinkedList<>();
		for(Almacen otro : escalas1){
			Vector<Vuelo> intermedios1 = 
					origen.getVuelosEnIntervaloDeTiempo(otro, fechaInicio, Fecha.suma(fechaInicio, Fecha.nextHora(tiempoVacio)));
				
			for(Vuelo intermedio1 : intermedios1){
				List<LinkedList<Vuelo>> intermedios2 = generaRutasConUnaEscala(otro, destino, intermedio1.getFechaLlegada(),
						Fecha.resta(tiempoVacio, Fecha.resta(intermedio1.getFechaSalida(), fechaInicio)),
						escalas2);
				for(LinkedList<Vuelo> lista : intermedios2){
					LinkedList<Vuelo> ruta = new LinkedList<>();
					ruta.add(intermedio1);
					ruta.addAll(lista);
					rutas.add(ruta);
				}
			}
		}
		return rutas;
	}

	public static List<Ruta> generaRutasDirectas(
			Paquete paquete, Almacen origen, Almacen destino,
			Fecha fechaInicio, Fecha tiempoVacio) {
		List<LinkedList<Vuelo> > listaVuelos = generaRutasDirectas(origen, destino, fechaInicio, tiempoVacio);
		LinkedList<Ruta> rutas = new LinkedList<>();
		for(LinkedList<Vuelo> vuelos : listaVuelos)
			rutas.add(new Ruta(vuelos, paquete));
		return rutas;
	}
	
	public static List<Ruta> generaRutasConUnaEscala(
			Paquete paquete, Almacen origen, Almacen destino,
			Fecha fechaInicio, Fecha tiempoVacio, List<Almacen> escalas1) {
		List<LinkedList<Vuelo> > listaVuelos = generaRutasConUnaEscala(origen, destino, fechaInicio, tiempoVacio, escalas1);
		LinkedList<Ruta> rutas = new LinkedList<>();
		for(LinkedList<Vuelo> vuelos : listaVuelos)
			rutas.add(new Ruta(vuelos, paquete));
		return rutas;
	}
	
	public static List<Ruta> generaRutasConDosEscalas(
			Paquete paquete, Almacen origen, Almacen destino,
			Fecha fechaInicio, Fecha tiempoVacio, List<Almacen> escalas1, List<Almacen> escalas2) {
		List<LinkedList<Vuelo> > listaVuelos = generaRutasConDosEscalas(origen, destino, fechaInicio, tiempoVacio, escalas1, escalas2);
		LinkedList<Ruta> rutas = new LinkedList<>();
		for(LinkedList<Vuelo> vuelos : listaVuelos)
			rutas.add(new Ruta(vuelos, paquete));
		return rutas;
	}
}
